package com.store.service.impl;

import cn.hutool.core.util.RandomUtil;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.store.domain.R;
import com.store.domain.dto.OrderDto;
import com.store.domain.entity.Book;
import com.store.domain.entity.Order;
import com.store.domain.entity.OrderItem;
import com.store.domain.entity.Shopcar;
import com.store.domain.vo.OrderItemVo;
import com.store.domain.vo.OrderVo;
import com.store.mapper.*;
import com.store.service.OrderService;
import com.store.utils.BeanCopyUtils;
import com.store.utils.ThreadLocalUtil;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Date;
import java.util.List;

/**
 * 订单表(Order)表服务实现类
 *
 * @author yu
 * @since 2024-06-26 01:12:42
 */
@Service("orderService")
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService {

    @Resource
    private UserMapper userMapper;
    @Override
    public R getPageOrder(Integer pageNum, Integer pageSize, Order order) {
        LambdaQueryWrapper<Order> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(order.getId() != null, Order::getId, order.getId());
        queryWrapper.eq(order.getStatus() != null, Order::getStatus, order.getStatus());
        Page<Order> page = new Page<>(pageNum, pageSize);
        page(page, queryWrapper);
        List<Order> orderList = page.getRecords();
        List<OrderVo> orderVos = BeanCopyUtils.copyBeanList(orderList, OrderVo.class);
        orderVos.forEach(orderVo -> {
            orderVo.setUsername(userMapper.selectById(orderVo.getUserId()).getUsername());
        });
        return R.success(page.getTotal(), orderVos);
    }

    @Resource
    private OrderItemMapper orderItemMapper;
    @Resource
    private BookMapper bookMapper;
    @Override
    public R getOrderById(String orderId) {
        Order order = getById(orderId);
        OrderVo orderVo = BeanCopyUtils.copyBean(order, OrderVo.class);
        LambdaQueryWrapper<OrderItem> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(OrderItem::getOrderId, orderId);
        List<OrderItem> orderItems = orderItemMapper.selectList(queryWrapper);
        List<OrderItemVo> orderItemVos = BeanCopyUtils.copyBeanList(orderItems, OrderItemVo.class);
        orderVo.setOrderItems(orderItemVos);
        //获取所有的钱
        double totalPrice = 0;
        for (OrderItemVo orderItemVo : orderItemVos){
            Book book = bookMapper.selectById(orderItemVo.getBookId());
            orderItemVo.setCover(book.getCover());
            orderItemVo.setName(book.getName());
            orderItemVo.setPrice(book.getPrice());
            orderItemVo.setTotalPrice(book.getPrice()*orderItemVo.getNum());
            totalPrice += orderItemVo.getTotalPrice();
        }
        orderVo.setTotalPrice(totalPrice);
        //获取下单用户
        orderVo.setUsername(userMapper.selectById(order.getUserId()).getUsername());
        if (order != null){
            return R.success(orderVo);
        } else {
            return R.error("订单不存在");
        }
    }

    @Override
    public R closeOrder(String orderId) {
        Order order = getById(orderId);
        if (order.getStatus() == 1){
            order.setStatus(5);
            boolean b = updateById(order);
            if (b){
                //获取所有item
                LambdaQueryWrapper<OrderItem> queryWrapper = new LambdaQueryWrapper<>();
                queryWrapper.eq(OrderItem::getOrderId, orderId);
                List<OrderItem> orderItems = orderItemMapper.selectList(queryWrapper);
                for (OrderItem orderItem : orderItems){
                    Book book = bookMapper.selectById(orderItem.getBookId());
                    book.setStoreNum(book.getStoreNum()+orderItem.getNum());
                    bookMapper.updateById(book);
                }
                return R.success("订单关闭成功");
            } else {
                return R.error("订单关闭失败");
            }
        }
        return R.error("只能关闭已创建未支付的订单");
    }

    @Override
    public R deliveryOrder(OrderDto orderDto) {
        Order order = BeanCopyUtils.copyBean(orderDto, Order.class);
        //只有已支付未发货的能够发货
        order.setId(orderDto.getOrderId());
        order.setStatus(3);
        boolean b = updateById(order);
        if (b){
            return R.success("发货成功");
        }
        return R.error("发货失败");
    }

    @Override
    public void exp(HttpServletResponse response) throws IOException {
        List<Order> orderList = list();
        ExcelWriter writer = ExcelUtil.getWriter(true);
        writer.addHeaderAlias("id", "订单号");
        writer.addHeaderAlias("userId", "用户id");
        writer.addHeaderAlias("createDate", "创建时间");
        writer.addHeaderAlias("status", "订单状态");
        writer.addHeaderAlias("payWay", "支付方式");
        writer.addHeaderAlias("payDate", "支付时间");
        writer.addHeaderAlias("trackingNumber", "快递单号");
        writer.addHeaderAlias("distributionMode", "配送方式");
        writer.addHeaderAlias("receivePhone", "收货人电话");
        writer.addHeaderAlias("receiveAddress", "收货人地址");
        writer.addHeaderAlias("receiveUsername", "收货人姓名");

        writer.write(orderList, true);

        response.setContentType("application/vnd.openxmlformats-officedoument.spreadsheetml.sheet;charset=utf-8");
        response.setCharacterEncoding("utf-8");
        String fileName = URLEncoder.encode("订单信息", "UTF-8");
        response.setHeader("Content-Disposition", "attachment;filename=" + fileName + ".xlsx");

        ServletOutputStream out = response.getOutputStream();
        writer.flush(out, true);
        out.close();
        writer.close();
    }

    @Override
    public R getUserOrder() {
        Integer userId = ThreadLocalUtil.getLocal();
        LambdaQueryWrapper<Order> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Order::getUserId, userId);
        List<Order> orderList = list(queryWrapper);
        return R.success(orderList);
    }

    @Override
    public R sureOrder(String orderId) {
        Order order = getById(orderId);
        order.setStatus(4);
        boolean b = updateById(order);
        if (b){
            return R.success("订单确认成功");
        }
        return R.error("订单确认失败");
    }

    @Resource
    private ShopcarMapper shopcarMapper;
    @Resource
    private OrderMapper orderMapper;
    @Transactional
    @Override
    public R submitOrder(OrderDto orderDto) {
        Order order = BeanCopyUtils.copyBean(orderDto, Order.class);
        //随机生成一个不重复的37位的字符串
        order.setId(RandomUtil.randomString(37));
        order.setUserId(ThreadLocalUtil.getLocal());
        order.setCreateDate(new Date());
        int i = orderMapper.insertOrder(order);
        if (i > 0){
            for (Integer shopCarId : orderDto.getShopCarIds()){
                Shopcar shopcar = shopcarMapper.selectById(shopCarId);
                OrderItem orderItem = new OrderItem();
                orderItem.setOrderId(order.getId());
                orderItem.setBookId(shopcar.getBookId());
                orderItem.setNum(shopcar.getNum());
                orderItemMapper.insert(orderItem);
                shopcarMapper.deleteById(shopCarId);
            }
        }
        //从购物车中删除

        return R.success("订单创建成功");
    }

    @Override
    public R payOrder(String id) {
        Order order = getById(id);
        order.setStatus(2);
        order.setPayWay("微信支付");
        order.setPayDate(new Date());
        boolean b = updateById(order);
        if (b){
            return R.success("支付成功");
        }
        return R.error("支付失败");
    }
}


